package com.leon.lifeenginespace.spring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;


/**
 * @description: beanFactory实现
 * @author: WT
 * @date: 2024/4/22 23:35
 * @Version 1.0
 **/
public class BeanFactory {
    //控制反转-》通过Bean的定义 交给DefaultlistableBeanFactory
    //bean的定义 (class scope 初始化，销毁)
    public static void main(String[] args) {

        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //bean对象生成方法
        AbstractBeanDefinition singleton =
                BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        //bean工厂注册
        //beanFactory缺少解析注解Configurable Bean的能力
        beanFactory.registerBeanDefinition("config", singleton);

        //给beanFactory添加一些常用的后处理器  让beanFactory解析注解
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });
        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }
        //bean 后处理器 针对bean的生命周期进行拓展
        //准备所有单例
        beanFactory.preInstantiateSingletons();
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().
                forEach(beanFactory::addBeanPostProcessor);








    }

    @Configurable
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }

    static class Bean1 {
        private static final Logger logger = LoggerFactory.getLogger(Bean1.class);
        @Autowired
        Bean2 bean2;

        public Bean1() {
            logger.info("构造Bean1");
        }

        public Bean2 getBean2() {
            return bean2;
        }
    }

    static class Bean2 {
        private static final Logger logger = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            logger.info("构造Bean2");
        }
    }
}